/*
 *  $Id: Land.cs 1233 2010-12-18 17:54:48Z thenn.erannor $
 *  This file is a part of Ragima CCG.
 *  (C) 2008-2010 Ragima development group.
 *
 *  Licensed under the terms of the GNU GPL License version 2.
 *
 */

using System;
using System.Collections.Generic;

using AgateLib;
using AgateLib.Geometry;

using Nereal.Serialization;

namespace Ragima {
    /// <summary>
    /// Тип цели: местность.
    /// </summary>
    public class LandTarget : TargetType {
        /// <summary>
        /// Цель: союзная местность.
        /// </summary>
        public static readonly LandTarget Own = new LandTarget(new Languages.Phrase("target.land.own"), true, false);
        /// <summary>
        /// Цель: вражеская местность.
        /// </summary>
        public static readonly LandTarget Enemy = new LandTarget(new Languages.Phrase("target.land.enemy"), false, true);
        /// <summary>
        /// Цель: любая местность.
        /// </summary>
        public static readonly LandTarget Both = new LandTarget(new Languages.Phrase("target.land.both"), true, true);

        private bool _own, _enemy;
        private TargetPredicate<Land> _condition;

        public LandTarget(Languages.Phrase notice, bool own, bool enemy) : this(notice, own, enemy, null) {
        }
        public LandTarget(Languages.Phrase notice, bool own, bool enemy, TargetPredicate<Land> condition) : base(notice) {
            _own = own;
            _enemy = enemy;
            _condition = condition;
        }

        public override bool IsRealTarget {
            get { return true; }
        }

        protected override void AutoSelectTab(Player player) {
            player.DefaultTab = TabType.Lands;
            player.SelectPlayer(_enemy && !_own ? player.Enemy : player);
        }

        /// <summary>
        /// Число целей равно числу местностей.
        /// </summary>
        public override int GetCount(AbstractObject caster) {
            int count = 0;
            if (_own)
                count += caster.Owner.Lands.Count;
            if (_enemy)
                count += caster.Owner.Enemy.Lands.Count;
            return count;
        }

        /// <summary>
        /// Целевые регионы: местности (без антимагии).
        /// </summary>
        public override bool AcceptRegion(Region region) {
            var plr = region as PlayerLandRegion;
            if (plr == null)
                return false;
            if (!(plr.IsEnemy ? _enemy : _own))
                return false;
            if (plr.Land.HasFlag<Affects.Antimagic>())
                return false;
            if (_condition != null && !_condition(Request, plr.Land))
                return false;
            return true;
        }

        public override TargetArgs GetArgs(Region region) {
            var plr = region as PlayerLandRegion;
            return plr != null ? new LandTargetArgs(Request.Player, Request.Caster, plr.Land) : null;
        }
    }

    [TypeId("land")]
    public class LandTargetArgs : TargetArgs<Land> {
        [Serialize, XmlName("target"), Reference(true, typeof(string), Serialization.Resolvers.GameLand)]
        private Land _target;

        public LandTargetArgs() {
        }
        public LandTargetArgs(Player player, AbstractObject caster, Land target) : base(player, caster) {
            _target = target;
        }

        public override Land Target {
            get { return _target; }
        }
    }
}
